
#include "land_graphics.h"

#define LAND_2D_CORE

#include "init.h"

static struct {
	unsigned texPos;
	LandDraw draw;
	LandTexture* drawTex;
}ctx = {0};

static void
beginDraw(LandScene* scene) {
	LandDraw* draw = &ctx.draw;
	landClearVertex(draw->vertex);
	draw->offset = draw->count = 0;
}

static void
readyDraw(LandScene* scene) {
	landUploadVertex(ctx.draw.vertex);
}

static void
preDraw(LandScene* scene, LandObj* obj) {
	LandImage* image = (LandImage*)obj;
	LandDraw* draw = &ctx.draw;
	LandVector* color = &image->obj.color;
	LandVector uv = { 0.f, 0.f, 1.f, 1.f };
	LandVertex* vertex = draw->vertex;
	image->offset = landGetListTotal(vertex->indexs);
	unsigned offset = landGetListTotal(vertex->points);
	image->count = landPushObjRect(draw->vertex,
		&obj->rect, &uv, color, &offset, &obj->transform);
}

static void
drawImage(LandScene* scene, LandObj* obj){
	LandImage* image = (LandImage*)obj;
	LandDraw* draw = &ctx.draw;

	if (draw == scene->draw) {
		if (ctx.drawTex == image->texture) {
			draw->count += image->count;
			return;
		}
	}
	if (scene->draw) {
		landDraw(scene->canvas, scene->draw);
	}
	draw->offset = image->offset;
	draw->count = image->count;
	draw->view = &scene->view;
	ctx.drawTex = image->texture;
	landUniformTex(draw, ctx.texPos, image->texture);
	scene->draw = draw;
}

static void
freeImage(LandRef* ref){
	LandImage* image = (LandImage*)ref;
	landReleaseRef(image->texture);
}

LAND_2D_API LandImage*
landNewImage(LandTexture* texture){
	landRetainRef(texture);
	LandImage* image = landNewExtendObj(sizeof(LandImage), freeImage);
	image->obj.preDraw = preDraw;
	image->obj.draw = drawImage;
	image->texture = texture;
	landObjSize(image,
		(LandFloat)texture->width, (LandFloat)texture->height);
	return image;
}

void
landInitImageContext(){
	LandDraw* draw = &ctx.draw;
	draw->depthTest = LAND_DEPTH_TEST_ALWAYS;
	draw->drawType = LAND_DRAW_TRIANGLES;
	draw->shader = landNewStdShader(LAND_STD_SHADER_COLOR_TEXTURE);
	draw->vertex = landNewVertex(128);
	ctx.texPos = landRegUniformTex(draw, "landBaseTexture", NULL);
	landRetainRef(draw->shader);
	landRetainRef(draw->vertex);
	LandSceneMod mod = {
		beginDraw,
		readyDraw,
	};
	landPushSceneMod(&mod);
}